	;; Riley Recycle
	;; A game somewhat based on Cookie Monster Munch
	;; Control character Riley with joypad direction and pick up
	;; recyclable and put it in the recycling bin

	;; MAIN-CPU program

	include CONSTANT.INC
	include RAM.INC

	;; Start of game code
        lea     RegSetup(pc),a5
        movem.l (a5)+,a3-a4

	;; seed the random number generator
	move.w	#$2010,RandomNumber
	
	;; initialize VDP
	move.w	#$8000,d0
	move.w	#(EndVDPSetup-StartVDPSetup-1),d1
	lea	StartVDPSetup(pc),a5
VDPInit:
	move.b	(a5)+,d0
	move.w	d0,(a4)
	addi.w	#$0100,d0
	dbf	d1,VDPInit

	;; supervisor mode and ignore all interrupts
	move    #$2700,sr

	;; copy the palettes to CRAM 0000
        move.l    #$c0000000,(a4)
        move.w   #((EndPalettes-StartPalettes)/2-1),d5
        lea      StartPalettes(pc),a5
        clr.l    d0
PalettesCopy:
        move.w   (a5)+,d0
        move.l   d0,(a3)
        dbf     d5,PalettesCopy

	;; vdp increment address by 2
        move.w   #$8f02,(a4)

	;; copy game tiles over VRAM 0400
	;; load font (same as sega cd default font, mostly for ROM)
        move.l  #$44000000,(a4)
        lea     StartFONTTiles(pc),a5
        move.w  #((EndFONTTiles-StartFONTTiles)/2-1),d5
FontCopy:
        move.w  (a5)+,d0
	move.w	d0,d1
	moveq	#3,d2
FontCopyUncompress:	
	move.w	d1,d0
	lsr.w	#1,d1
	andi.w  #$1111,d0
	move.w  d0,(a3)
	dbf	d2,FontCopyUncompress
        dbf     d5,FontCopy

	;; copy game tiles over VRAM 0800
        move.l   #$50000000,(a4)
        lea      StartTiles(pc),a5
        move.w   #((EndTiles-StartTiles)/2-1),d5
TileCopy:
        move.w   (a5)+,(a3)
        dbf      d5,TileCopy
	
	;; clear flags (0 is default value for all bits)
	clr.b	Flags
	
	;; joystick initilization
        moveq     #$40,d0
        move.b    d0,$a10009
        move.b    d0,$a1000b
        move.b    d0,$a1000d

	;; title and start screens
	include TITLE.ASM
	;; level select
	include LEVELSEL.ASM
	;; common routines for levels
	include LEVELCOM.ASM
	;; levels
	include LEVEL0.ASM
	include	LEVEL1.ASM
	include LEVEL2.ASM
	include	LEVEL3.ASM
	include	LEVEL4.ASM

	;; routines for vdp, vint, and sprites
	include VDP.ASM


	;; returns next random in d0 (and in RandomNumber)
	;; y ^= y << a ; y ^= y >> b ; y ^= y << c
	;; can use (1,5,2),(1,7,4),(2,5,1),(4,3,7),(4,7,1),(7,3,4)
NextRandom:
	move.w  d1,-(a7)
	move.w	RandomNumber,d0
	move.w	d0,d1
	lsl.w	#1,d0
	eor.w   d1,d0
	move.w	d0,d1
	lsr.w	#7,d0
	eor.w   d1,d0
	move.w	d0,d1
	lsl.w	#4,d0
	eor.w   d1,d0
	move.w	d0,RandomNumber
	move.w  (a7)+,d1
	rts

VBlank:
	;; save registers we will use
	movem.l  d0-d1/a5,-(a7)
	addq.w  #1,VintCounter
	addq.w  #1,VintWait
	;; vdp increment address by 2
	move.w  #$8f02,(a4)
	;; VRAM D800
	move.l   #$58000003,(a4)
        move.w   #((EndSpriteRAM-StartSpriteRAM)/2-1),d0
        lea      StartSpriteRAM,a5
VintSpriteCopy:
        move.w   (a5)+,(a3)
        dbf      d0,VintSpriteCopy
	;; allow interrupts again
        and.w    #$f8ff,sr

	;; makes random numbers based on time too
	bsr.s	NextRandom

	;; update Port1Hold and Port1Press
	lea	$a10003,a5
	lea	Port1Hold,a6
	bsr.s	VintUpdatePort

	;; update Port2Hold and Port2Press
	adda.w	#2,a5
	;; a6 already updated to point to Port2Hold
	bsr.s	VintUpdatePort

	;; restore registers we will use
	movem.l  (a7)+,d0-d1/a5
	;; indicate we saw a vint
        bset     #GotVintFlag,Flags
        rte

	;; update port hold and port press bytes
	;; a5 port address
	;; a6 address of hold/pressed bytes
VintUpdatePort:
	;; get port1 info
        move.b   #$40,(a5)
        nop
        nop
        move.b   (a5),d0
	;; d0 has XXCBRLDU
        andi.b   #$3f,d0
        move.b   #$00,(a5)
        nop
        nop
        move.b   (a5),d1
	;; d1 has XXSARLDU
	and.b    #$30,d1
        lsl.b    #2,d1
	or.b     d1,d0
        not.b    d0
	;; d0 now has SACBRLDU
	btst	 #bitStart,d0
	beq.s	 VintUpdatePortSkipStartFlag
	bset	 #StartButtonFlag,Flags
VintUpdatePortSkipStartFlag:
	;; get old hold value to determine press value
	;; press value is any new button not pressed in the last update
        move.b   (a6),d1
	eor.b	 d0,d1
	and.b	 d0,d1
	;; store hold and press values
        move.b   d0,(a6)+
        move.b   d1,(a6)+

	rts
	

WaitForVint:
	movem.l	d0/a5,-(a7)
	;; cannot tst.l a5...
	move.l  VintAnimate,d0
	tst.l   d0
	beq.s   WaitForVintSkipAnimate
	movea.l	d0,a5
	jsr     (a5)
WaitForVintSkipAnimate:
	movem.l	(a7)+,d0/a5
WaitForVintLoop:
        bclr    #GotVintFlag,Flags
        beq.s   WaitForVintLoop
	rts

	
	
RegSetup:
        dc.l    $00c00000,$00c00004

	include ROAD2.ASM
	include ROAD6.ASM


StartScoreWord:	
	dc.b "Score 000"
StartRowScoreWord:
	dc.b " Word ___"
EndScoreWord:	

StartPalettes:
	include PAL.ASM
EndPalettes:

	include	FONT.ASM
	
StartTiles:
	;; 30 tiles
	include RILEY.ASM
	;; 6 tiles
	include BIN.ASM
	;; 9 tiles
	include BORDER.ASM
	;; 56 tiles
	include TRUCK.ASM
	;; 16 tiles
	include BORDER2.ASM
EndTiles:

StartWord3List:
	include WORD3.ASM
EndWord3List:
	